"""
AKShare数据提供者模块 - 提供AKShare数据接口
"""

import akshare as ak
import pandas as pd
from typing import Dict, List, Optional, Union, Any
import logging
import datetime
import time
import re

# 导入常量
from FDAS.data.constants import (
    ASSET_TYPE_STOCK,
    ASSET_TYPE_FUTURE,
    ASSET_TYPE_OPTION,
    ASSET_TYPE_FUND,
    ASSET_TYPE_INDEX,
    ASSET_TYPE_ETF
)

class AKShareProvider:
    """AKShare数据提供者"""
    
    def __init__(self):
        """初始化数据提供者"""
        self.logger = logging.getLogger(self.__class__.__name__)
    
    def get_stock_list(self) -> pd.DataFrame:
        """
        获取股票列表
        
        返回:
            包含股票代码和名称的DataFrame
        """
        try:
            # 获取A股股票列表
            df = ak.stock_info_a_code_name()
            # 重命名列
            df.columns = ['code', 'name']
            return df
        except Exception as e:
            self.logger.error(f"获取股票列表失败: {str(e)}")
            return pd.DataFrame(columns=['code', 'name'])
    
    def get_fund_list(self) -> pd.DataFrame:
        """
        获取基金列表
        
        返回:
            包含基金代码和名称的DataFrame
        """
        try:
            # 获取基金列表
            df = ak.fund_name_em()
            # 重命名列
            df.columns = ['code', 'name', 'type']
            return df[['code', 'name']]
        except Exception as e:
            self.logger.error(f"获取基金列表失败: {str(e)}")
            return pd.DataFrame(columns=['code', 'name'])
    
    def get_future_list(self) -> pd.DataFrame:
        """
        获取期货列表
        
        返回:
            包含期货代码和名称的DataFrame
        """
        try:
            # 获取期货列表
            df = ak.futures_symbol_mark()
            # 重命名列
            df.columns = ['code', 'name', 'market']
            return df[['code', 'name']]
        except Exception as e:
            self.logger.error(f"获取期货列表失败: {str(e)}")
            return pd.DataFrame(columns=['code', 'name'])
    
    def get_option_list(self) -> pd.DataFrame:
        """
        获取期权列表
        
        返回:
            包含期权代码和名称的DataFrame
        """
        try:
            # 获取期权列表
            df = ak.option_cffex_hs300_list_sina()
            # 重命名列
            df.columns = ['code', 'name']
            return df
        except Exception as e:
            self.logger.error(f"获取期权列表失败: {str(e)}")
            return pd.DataFrame(columns=['code', 'name'])
    
    def get_index_list(self) -> pd.DataFrame:
        """
        获取指数列表
        
        返回:
            包含指数代码和名称的DataFrame
        """
        try:
            # 获取指数列表
            df = ak.index_stock_info()
            # 重命名列
            df.columns = ['code', 'name', 'market']
            return df[['code', 'name']]
        except Exception as e:
            self.logger.error(f"获取指数列表失败: {str(e)}")
            return pd.DataFrame(columns=['code', 'name'])
    def get_etf_list(self) -> pd.DataFrame:
        """
        获取ETF列表
        
        返回:
            包含ETF代码和名称的DataFrame
        """
        try:
            # 获取ETF列表
            df = ak.fund_etf_category_sina()
            
            # 检查数据格式
            if len(df.columns) < 4:
                raise ValueError("ETF列表数据列数不足")
                
            # 提取必要列
            required_columns = ['symbol', 'name', 'fund_fee', 'fund_size']
            if not all(col in df.columns for col in required_columns):
                df = df.iloc[:, :4]  # 取前4列作为默认处理
                df.columns = ['symbol', 'name', 'fund_fee', 'fund_size']
                
            # 重命名列以匹配下游代码
            df = df[['symbol', 'name']].rename(columns={'symbol': 'code'})
            return df
            df = ak.fund_etf_category_sina()
            # 重命名列
            df.columns = ['code', 'name', 'price', 'change']
            return df[['code', 'name']]
        except Exception as e:
            self.logger.error(f"获取ETF列表失败: {str(e)}")
            return pd.DataFrame(columns=['code', 'name'])
    
    def get_asset_list(self, asset_type: str) -> pd.DataFrame:
        """
        获取资产列表
        
        参数:
            asset_type: 资产类型
            
        返回:
            包含资产代码和名称的DataFrame
        """
        if asset_type == ASSET_TYPE_STOCK:
            return self.get_stock_list()
        elif asset_type == ASSET_TYPE_FUND:
            return self.get_fund_list()
        elif asset_type == ASSET_TYPE_FUTURE:
            return self.get_future_list()
        elif asset_type == ASSET_TYPE_OPTION:
            return self.get_option_list()
        elif asset_type == ASSET_TYPE_INDEX:
            return self.get_index_list()
        elif asset_type == ASSET_TYPE_ETF:
            return self.get_etf_list()
        else:
            self.logger.error(f"不支持的资产类型: {asset_type}")
            return pd.DataFrame(columns=['code', 'name'])
    
    def get_asset_history(self, symbol: str, asset_type: str, start_date: str = None, end_date: str = None, 
                         period: str = "daily", adjust: str = "qfq", 
                         limit: int = None) -> pd.DataFrame:
        """
        获取资产历史数据
        
        参数:
            symbol: 资产代码
            asset_type: 资产类型
            start_date: 开始日期，格式：YYYYMMDD
            end_date: 结束日期，格式：YYYYMMDD
            period: 周期，可选值：daily, weekly, monthly
            adjust: 复权方式，可选值：qfq(前复权), hfq(后复权), ""(不复权)
            limit: 限制返回的数据条数
            
        返回:
            包含历史数据的DataFrame
        """
        try:
            # 根据资产类型调用不同的获取历史数据方法
            if asset_type == ASSET_TYPE_STOCK:
                return self.get_stock_history(symbol, start_date, end_date, period, adjust, limit)
            elif asset_type == ASSET_TYPE_FUTURE:
                # 期货历史数据
                try:
                    # 处理交易所代码转换
                    exchange_map = {
                        '上海': 'SHF',
                        '上期所': 'SHF',
                        '大商所': 'DCE',
                        '郑商所': 'CZC',
                        'INE': 'SHF',  # 上海国际能源交易中心
                        'CL': 'NYMEX'  # 纽约商业交易所原油
                    }
                    
                    # 提取交易所代码
                    if symbol.startswith(tuple(exchange_map.keys())):
                        # 中文或国际代码
                        exchange = next(k for k in exchange_map.keys() if symbol.startswith(k))
                        exchange_code = exchange_map[exchange]
                        contract_code = symbol[len(exchange):]
                    elif len(symbol) >= 2 and symbol[:2].isalpha():
                        # 标准交易所代码
                        exchange_code = symbol[:2].upper()
                        contract_code = symbol[2:]
                    else:
                        self.logger.error(f"无效的期货代码格式: {symbol}")
                        return pd.DataFrame()

                    # 根据交易所选择接口
                    if exchange_code == 'DCE':
                        df = ak.futures_main_sina(symbol=contract_code)
                    elif exchange_code == 'SHF':
                        df = ak.futures_shfe_daily(symbol=contract_code)
                    elif exchange_code == 'CZC':
                        df = ak.futures_czce_daily(symbol=contract_code)
                    elif exchange_code == 'NYMEX':
                        df = ak.futures_foreign_hist(symbol=contract_code, exchange="NYMEX")
                    else:
                        self.logger.error(f"不支持的交易所代码: {exchange_code}")
                        return pd.DataFrame()
                        
                    # 标准化列名
                    column_mapping = {
                        'date': '日期',
                        'open': '开盘价',
                        'high': '最高价',
                        'low': '最低价',
                        'close': '收盘价',
                        'volume': '成交量',
                        'open_interest': '持仓量'
                    }
                    df = df.rename(columns=column_mapping)
                    return df
                except Exception as e:
                    self.logger.error(f"获取期货历史数据失败: {str(e)}")
                    return pd.DataFrame()
                    
            elif asset_type == ASSET_TYPE_FUND or asset_type == ASSET_TYPE_ETF:
                # 基金和ETF使用相同的历史数据获取方法
                try:
                    # 尝试使用基金历史数据获取方法
                    df = ak.fund_open_fund_info_em(symbol=symbol, start_date=start_date, end_date=end_date)
                    # 确保基本列存在
                    if '净值日期' in df.columns:
                        df.rename(columns={'净值日期': '日期'}, inplace=True)
                    if '单位净值' not in df.columns:
                        df['单位净值'] = None
                    if '累计净值' not in df.columns:
                        df['累计净值'] = None
                    return df
                except Exception as e:
                    self.logger.error(f"获取基金/ETF历史数据失败: {str(e)}")
                    return pd.DataFrame(columns=['日期', '单位净值', '累计净值'])
            elif asset_type == ASSET_TYPE_FUTURE:
                # 获取期货历史数据
                try:
                    # 尝试多种期货数据获取方式
                    try:
                        # 方式1: 使用主力合约接口
                        df = ak.futures_main_sina(symbol=symbol.lower())
                    except Exception:
                        # 方式2: 使用期货连续合约接口
                        df = ak.futures_zh_spot(symbol=symbol.lower())
                    
                    # 标准化列名
                    column_mapping = {
                        'date': '日期',
                        'open': '开盘价',
                        'high': '最高价',
                        'low': '最低价',
                        'close': '收盘价',
                        'volume': '成交量'
                    }
                    df = df.rename(columns=column_mapping)
                    
                    # 确保基本列存在
                    required_cols = ['日期', '开盘价', '最高价', '最低价', '收盘价', '成交量']
                    for col in required_cols:
                        if col not in df.columns:
                            df[col] = None
                    return df
                except Exception as e:
                    self.logger.error(f"获取期货历史数据失败: {str(e)}")
                    return pd.DataFrame(columns=['日期', '开盘价', '最高价', '最低价', '收盘价', '成交量'])
            elif asset_type == ASSET_TYPE_OPTION:
                # 获取期权历史数据
                try:
                    # 尝试获取期权历史数据
                    df = ak.option_sina_sse_daily(symbol=symbol)
                    # 确保基本列存在
                    required_cols = ['日期', '开盘价', '最高价', '最低价', '收盘价', '成交量']
                    for col in required_cols:
                        if col not in df.columns:
                            df[col] = None
                    return df
                except Exception as e:
                    self.logger.error(f"获取期权历史数据失败: {str(e)}")
                    return pd.DataFrame(columns=['日期', '开盘价', '最高价', '最低价', '收盘价', '成交量'])
            elif asset_type == ASSET_TYPE_INDEX:
                # 获取指数历史数据
                try:
                    df = ak.index_zh_a_hist(symbol=symbol, start_date=start_date, end_date=end_date, period=period)
                    # 重命名列
                    if '日期' not in df.columns and '指数代码' in df.columns:
                        df.rename(columns={'指数代码': '日期'}, inplace=True)
                    # 确保基本列存在
                    required_cols = ['日期', '开盘', '收盘', '最高', '最低', '成交量']
                    for col in required_cols:
                        if col not in df.columns:
                            df[col] = None
                    # 限制数据条数
                    if limit is not None and len(df) > limit:
                        df = df.iloc[-limit:]
                    return df
                except Exception as e:
                    self.logger.error(f"获取指数历史数据失败: {str(e)}")
                    return pd.DataFrame(columns=['日期', '开盘', '收盘', '最高', '最低', '成交量'])
            else:
                self.logger.error(f"不支持的资产类型: {asset_type}")
                return pd.DataFrame()
        except Exception as e:
            self.logger.error(f"获取资产历史数据失败: {str(e)}")
            return pd.DataFrame()
    
    def get_stock_history(self, symbol: str, start_date: str = None, end_date: str = None, 
                          period: str = "daily", adjust: str = "qfq", 
                          limit: int = None) -> pd.DataFrame:
        """
        获取股票历史数据
        
        参数:
            symbol: 股票代码
            start_date: 开始日期，格式：YYYYMMDD
            end_date: 结束日期，格式：YYYYMMDD
            period: 周期，可选值：daily, weekly, monthly
            adjust: 复权方式，可选值：qfq(前复权), hfq(后复权), ""(不复权)
            limit: 限制返回的数据条数
            
        返回:
            包含历史数据的DataFrame
        """
        try:
            # 获取股票历史数据
            df = ak.stock_zh_a_hist(
                symbol=symbol, 
                period=period, 
                start_date=start_date, 
                end_date=end_date, 
                adjust=adjust
            )
            
            # 重命名列 - 确保列名与实际数据列数匹配
            columns = ['日期', '开盘', '收盘', '最高', '最低', '成交量', '成交额', '振幅', '涨跌幅', '涨跌额', '换手率']
            # 检查实际列数并调整
            if len(df.columns) == 12:
                columns.append('昨收')
            df.columns = columns
            
            # 限制数据条数
            if limit is not None and len(df) > limit:
                df = df.iloc[-limit:]
            
            return df
        except Exception as e:
            self.logger.error(f"获取股票历史数据失败: {str(e)}")
            return pd.DataFrame(columns=['日期', '开盘', '收盘', '最高', '最低', '成交量', '成交额', '振幅', '涨跌幅', '涨跌额', '换手率'])
    
    def get_stock_basic_info(self, symbol: str) -> Dict[str, Any]:
        """
        获取股票基本信息
        
        参数:
            symbol: 股票代码
            
        返回:
            包含股票基本信息的字典
        """
        try:
            # 获取股票基本信息
            df = ak.stock_individual_info_em(symbol=symbol)
            
            # 转换为字典 - 使用推荐的方式访问Series元素
            info_dict = {}
            for _, row in df.iterrows():
                # 使用iloc而不是位置索引，避免FutureWarning
                info_dict[row.iloc[0]] = row.iloc[1]
            
            return info_dict
        except Exception as e:
            self.logger.error(f"获取股票基本信息失败: {str(e)}")
            return {}
    
    def get_fund_basic_info(self, symbol: str) -> Dict[str, Any]:
        """
        获取基金基本信息
        
        参数:
            symbol: 基金代码
            
        返回:
            包含基金基本信息的字典
        """
        try:
            # 尝试获取基金基本信息
            df = ak.fund_info_index_em(symbol=symbol)
            
            if df.empty:
                return {
                    "code": symbol,
                    "name": "未知基金",
                    "type": "未知",
                    "asset_type": ASSET_TYPE_FUND
                }
            
            # 转换为字典
            info_dict = {}
            for _, row in df.iterrows():
                key = row.iloc[0]
                value = row.iloc[1]
                info_dict[key] = value
            
            # 添加必要的字段
            info_dict["code"] = symbol
            info_dict["asset_type"] = ASSET_TYPE_FUND
            
            return info_dict
        except Exception as e:
            self.logger.error(f"获取基金基本信息失败: {str(e)}")
            return {
                "code": symbol,
                "name": "未知基金",
                "type": "未知",
                "asset_type": ASSET_TYPE_FUND
            }
    
    def get_etf_basic_info(self, symbol: str) -> Dict[str, Any]:
        """
        获取ETF基本信息
        
        参数:
            symbol: ETF代码
            
        返回:
            包含ETF基本信息的字典
        """
        try:
            # 首先尝试使用基金信息接口
            fund_info = self.get_fund_basic_info(symbol)
            
            # 添加ETF特有信息
            fund_info["asset_type"] = ASSET_TYPE_ETF
            
            # 尝试获取ETF指数追踪信息
            try:
                etf_df = ak.fund_etf_fund_daily_em(symbol=symbol)
                if not etf_df.empty and "跟踪标的" in etf_df.columns:
                    fund_info["tracked_index"] = etf_df.iloc[0]["跟踪标的"]
            except Exception:
                pass
            
            return fund_info
        except Exception as e:
            self.logger.error(f"获取ETF基本信息失败: {str(e)}")
            return {
                "code": symbol,
                "name": "未知ETF",
                "type": "ETF",
                "asset_type": ASSET_TYPE_ETF
            }
    
    def get_future_basic_info(self, symbol: str) -> Dict[str, Any]:
        """
        获取期货基本信息
        
        参数:
            symbol: 期货代码
            
        返回:
            包含期货基本信息的字典
        """
        try:
            # 尝试获取期货合约信息
            futures_df = ak.futures_contract_detail(symbol=symbol.upper())
            
            if futures_df.empty:
                return {
                    "code": symbol,
                    "name": "未知期货",
                    "asset_type": ASSET_TYPE_FUTURE
                }
            
            # 构造基本信息字典
            info_dict = {
                "code": symbol,
                "asset_type": ASSET_TYPE_FUTURE
            }
            
            # 尝试从DataFrame中提取常用字段
            common_fields = {
                "交易品种": "name", 
                "交割月份": "delivery_month",
                "交易单位": "unit",
                "最小变动价位": "tick_size",
                "涨跌停板幅度": "limit_range",
                "最后交易日": "last_trading_day",
                "交割日期": "delivery_date",
                "交易代码": "trading_code"
            }
            
            for chinese_field, english_field in common_fields.items():
                if chinese_field in futures_df.columns:
                    info_dict[english_field] = futures_df.iloc[0][chinese_field]
            
            return info_dict
        except Exception as e:
            self.logger.error(f"获取期货基本信息失败: {str(e)}")
            return {
                "code": symbol,
                "name": "未知期货",
                "asset_type": ASSET_TYPE_FUTURE
            }
    
    def get_option_basic_info(self, symbol: str) -> Dict[str, Any]:
        """
        获取期权基本信息
        
        参数:
            symbol: 期权代码
            
        返回:
            包含期权基本信息的字典
        """
        try:
            # 尝试获取期权基本信息
            try:
                option_df = ak.option_current_em()
                # 过滤出指定期权
                if not option_df.empty and "代码" in option_df.columns:
                    option_info = option_df[option_df["代码"] == symbol]
                    if not option_info.empty:
                        # 转换为字典
                        info_dict = option_info.iloc[0].to_dict()
                        # 添加必要字段
                        info_dict["code"] = symbol
                        info_dict["asset_type"] = ASSET_TYPE_OPTION
                        return info_dict
            except Exception:
                pass
            
            # 如果上面的方法失败，尝试使用希腊字母接口获取基本信息
            greek_metrics = self.get_option_greek_metrics(symbol)
            if greek_metrics:
                greek_metrics["code"] = symbol
                greek_metrics["asset_type"] = ASSET_TYPE_OPTION
                return greek_metrics
            
            # 如果都失败，返回基本信息
            return {
                "code": symbol,
                "name": "未知期权",
                "asset_type": ASSET_TYPE_OPTION
            }
        except Exception as e:
            self.logger.error(f"获取期权基本信息失败: {str(e)}")
            return {
                "code": symbol,
                "name": "未知期权",
                "asset_type": ASSET_TYPE_OPTION
            }
    
    def get_index_basic_info(self, symbol: str) -> Dict[str, Any]:
        """
        获取指数基本信息
        
        参数:
            symbol: 指数代码
            
        返回:
            包含指数基本信息的字典
        """
        try:
            # 尝试获取指数基本信息
            index_df = ak.index_stock_info()
            
            # 过滤出指定指数
            if not index_df.empty and "代码" in index_df.columns:
                index_info = index_df[index_df["代码"] == symbol]
                if not index_info.empty:
                    # 转换为字典
                    info_dict = {
                        "code": symbol,
                        "name": index_info.iloc[0]["名称"],
                        "market": index_info.iloc[0]["市场"],
                        "asset_type": ASSET_TYPE_INDEX
                    }
                    return info_dict
            
            # 如果未找到指数信息，尝试使用成分股接口获取信息
            try:
                components_df = self.get_index_components(symbol)
                if not components_df.empty:
                    # 如果能获取到成分股，说明这是有效的指数
                    return {
                        "code": symbol,
                        "name": f"指数{symbol}",
                        "asset_type": ASSET_TYPE_INDEX,
                        "component_count": len(components_df)
                    }
            except Exception:
                pass
            
            # 如果都失败，返回基本信息
            return {
                "code": symbol,
                "name": "未知指数",
                "asset_type": ASSET_TYPE_INDEX
            }
        except Exception as e:
            self.logger.error(f"获取指数基本信息失败: {str(e)}")
            return {
                "code": symbol,
                "name": "未知指数",
                "asset_type": ASSET_TYPE_INDEX
            }
    
    def get_stock_valuation(self, symbol: str) -> pd.DataFrame:
        """
        获取股票估值数据
        
        参数:
            symbol: 股票代码
            
        返回:
            包含股票估值数据的DataFrame
        """
        try:
            # 尝试多种方法获取估值数据
            try:
                # 尝试方法1: 使用股票指标接口
                df = ak.stock_a_indicator_lg(symbol=symbol)
            except (AttributeError, TypeError):
                try:
                    # 尝试方法2: 使用东方财富股票指标接口
                    df = ak.stock_financial_analysis_indicator(symbol=symbol)
                    
                    # 如果成功，提取估值相关列
                    if not df.empty:
                        # 尝试找到包含PE、PB等关键词的列
                        pe_cols = [col for col in df.columns if 'PE' in col or '市盈率' in col]
                        pb_cols = [col for col in df.columns if 'PB' in col or '市净率' in col]
                        
                        # 创建新的DataFrame只包含估值数据
                        current_date = datetime.datetime.now().strftime('%Y-%m-%d')
                        val_data = {
                            '日期': [current_date],
                            '数据日期': [current_date]  # 添加数据日期列
                        }
                        
                        # 添加找到的PE列
                        if pe_cols:
                            val_data['PE(TTM)'] = [df.iloc[0][pe_cols[0]] if not df.empty else None]
                        else:
                            val_data['PE(TTM)'] = [None]
                            
                        # 添加找到的PB列
                        if pb_cols:
                            val_data['市净率'] = [df.iloc[0][pb_cols[0]] if not df.empty else None]
                        else:
                            val_data['市净率'] = [None]
                            
                        # 添加其他估值指标
                        val_data['市销率'] = [None]
                        val_data['市现率'] = [None]
                        
                        df = pd.DataFrame(val_data)
                except (AttributeError, TypeError):
                    # 如果所有方法都失败，创建一个基本的估值DataFrame
                    current_date = datetime.datetime.now().strftime('%Y-%m-%d')
                    df = pd.DataFrame({
                        '日期': [current_date],
                        '数据日期': [current_date],  # 添加数据日期列
                        'PE(TTM)': [None],
                        '市净率': [None],
                        '市销率': [None],
                        '市现率': [None]
                    })
            
            # 确保包含必要的列
            if 'PE(TTM)' not in df.columns and '市盈率(TTM)' in df.columns:
                df['PE(TTM)'] = df['市盈率(TTM)']
            if '市净率' not in df.columns and 'PB' in df.columns:
                df['市净率'] = df['PB']
                
            # 确保至少有这些基本列
            for col in ['日期', 'PE(TTM)', '市净率', '市销率', '市现率']:
                if col not in df.columns:
                    df[col] = None
            
            # 添加"数据日期"列，用于估值图表
            if '数据日期' not in df.columns and '日期' in df.columns:
                df['数据日期'] = df['日期']
            
            return df
        except Exception as e:
            self.logger.error(f"获取股票估值数据失败: {str(e)}")
            # 返回一个包含基本列的空DataFrame
            current_date = datetime.datetime.now().strftime('%Y-%m-%d')
            return pd.DataFrame({
                '日期': [current_date],
                '数据日期': [current_date],  # 添加数据日期列
                'PE(TTM)': [None],
                '市净率': [None],
                '市销率': [None],
                '市现率': [None]
            })
    
    def get_stock_financial(self, symbol: str,start_year:str=None) -> Dict[str, pd.DataFrame]:
        """
        获取股票财务数据
        
        参数:
            symbol: 股票代码
            
        返回:
            包含股票财务数据的字典，键为财务报表类型，值为DataFrame
        """
        if not start_year:
            start_year = str(datetime.datetime.now().year-3)
        
        try:
            # 初始化空的DataFrame
            balance_sheet = pd.DataFrame()
            income_statement = pd.DataFrame()
            cash_flow = pd.DataFrame()
            indicators = pd.DataFrame()
            
            # 获取资产负债表
            try:
                balance_sheet = ak.stock_financial_debt_ths(symbol=symbol,indicator="按年度")
                # 加强数据校验
                if not isinstance(balance_sheet, pd.DataFrame) or balance_sheet.empty:
                    self.logger.warning(f"资产负债表数据异常，symbol: {symbol}")
                    balance_sheet = pd.DataFrame(columns=["REPORT_DATE", "TOTAL_ASSETS", "TOTAL_LIABILITIES"])
                else:
                    # 标准化列名
                    balance_sheet.columns = balance_sheet.columns.str.upper()
                    # 添加必要字段
                    if "REPORT_DATE" not in balance_sheet.columns:
                        balance_sheet["REPORT_DATE"] = datetime.datetime.now().strftime('%Y-%m-%d')
            except Exception as e:
                self.logger.error(f"获取资产负债表失败: {str(e)}")
                balance_sheet = pd.DataFrame()
            
            # 获取利润表
            try:
                income_statement = ak.stock_financial_benefit_ths(symbol=symbol,indicator="按年度")
                # 加强数据校验
                if income_statement is None or not isinstance(income_statement, pd.DataFrame) or income_statement.empty:
                    self.logger.warning(f"利润表数据异常，symbol: {symbol}")
                    income_statement = pd.DataFrame(columns=["REPORT_DATE", "TOTAL_REVENUE", "NET_PROFIT"])
                else:
                    # 标准化列名
                    income_statement.columns = income_statement.columns.str.upper()
                    # 添加必要字段
                    if "REPORT_DATE" not in income_statement.columns:
                        income_statement["REPORT_DATE"] = datetime.datetime.now().strftime('%Y-%m-%d')
            except Exception as e:
                self.logger.error(f"获取利润表失败: {str(e)}")
                income_statement = pd.DataFrame()
            
            # 获取现金流量表
            try:
                cash_flow = ak.stock_financial_cash_ths(symbol=symbol,indicator="按年度")
                # 加强数据校验
                if cash_flow is None or not isinstance(cash_flow, pd.DataFrame) or cash_flow.empty:
                    self.logger.warning(f"现金流量表数据异常，symbol: {symbol}")
                    cash_flow = pd.DataFrame(columns=["REPORT_DATE", "NET_CASH_FLOW", "INVESTING_ACTIVITIES", "FINANCING_ACTIVITIES"])
                else:
                    # 标准化列名
                    cash_flow.columns = cash_flow.columns.str.upper()
                    # 添加必要字段
                    if "REPORT_DATE" not in cash_flow.columns:
                        cash_flow["REPORT_DATE"] = datetime.datetime.now().strftime('%Y-%m-%d')
            except Exception as e:
                self.logger.error(f"获取现金流量表失败: {str(e)}")
                cash_flow = pd.DataFrame()
            
            # 获取财务指标
            try:
                indicators = ak.stock_financial_analysis_indicator(symbol=symbol,start_year=start_year)
                # 确保返回的是DataFrame
                if indicators is None:
                    indicators = pd.DataFrame()
            except Exception as e:
                self.logger.error(f"获取财务指标失败: {str(e)}")
                indicators = pd.DataFrame()
            
            return {
                "balance_sheet": balance_sheet,
                "income_statement": income_statement,
                "cash_flow": cash_flow,
                "indicators": indicators
            }
        except Exception as e:
            self.logger.error(f"获取股票财务数据失败: {str(e)}")
            return {
                "balance_sheet": pd.DataFrame(),
                "income_statement": pd.DataFrame(),
                "cash_flow": pd.DataFrame(),
                "indicators": pd.DataFrame()
            }
    
    def get_stock_fund_flow(self, symbol: str) -> Dict[str, Any]:
        """
        获取股票资金流向数据
        
        参数:
            symbol: 股票代码
            
        返回:
            包含股票资金流向数据的字典
        """
        try:
            # AKShare API已更新，使用新的资金流向数据获取方法
            # 获取个股资金流向数据 - 注意API变更，可能需要不同的参数
            try:
                # 尝试新的API调用方式
                df = ak.stock_individual_fund_flow_rank(symbol=symbol)
            except TypeError:
                # 如果symbol参数不被接受，尝试不带参数调用
                try:
                    df = ak.stock_individual_fund_flow_rank()
                    # 如果成功，尝试过滤出特定股票的数据
                    if not df.empty and '代码' in df.columns:
                        df = df[df['代码'] == symbol]
                except Exception:
                    # 如果仍然失败，尝试其他可能的API
                    try:
                        df = ak.stock_individual_fund_flow()
                        # 尝试过滤
                        if not df.empty and '股票代码' in df.columns:
                            df = df[df['股票代码'] == symbol]
                    except Exception:
                        # 创建一个空的DataFrame
                        df = pd.DataFrame()
            
            # 获取行业资金流向数据
            try:
                industry_df = ak.stock_sector_fund_flow_rank(indicator="今日")
            except Exception:
                # 如果参数变更，尝试不带参数调用
                try:
                    industry_df = ak.stock_sector_fund_flow_rank()
                except Exception:
                    # 创建一个空的DataFrame
                    industry_df = pd.DataFrame()
            
            return {
                "individual": df.to_dict('records') if not df.empty else [],
                "industry": industry_df.to_dict('records') if not industry_df.empty else []
            }
        except Exception as e:
            self.logger.error(f"获取股票资金流向数据失败: {str(e)}")
            return {
                "individual": [],
                "industry": []
            }
    
    def get_stock_news(self, symbol: str) -> List[Dict[str, Any]]:
        """
        获取股票相关新闻
        
        参数:
            symbol: 股票代码
            
        返回:
            包含股票相关新闻的列表
        """
        try:
            # 获取股票相关新闻
            df = ak.stock_news_em(symbol=symbol)
            
            # 转换为列表
            news_list = []
            for _, row in df.iterrows():
                news_list.append({
                    "新闻标题": row["新闻标题"],
                    "发布时间": row["发布时间"],
                    "文章来源": row["文章来源"],
                    "新闻链接": row["新闻链接"]
                })
            
            return news_list
        except Exception as e:
            self.logger.error(f"获取股票相关新闻失败: {str(e)}")
            return []
    
    def get_stock_shareholders(self, symbol: str) -> Dict[str, Any]:
        """
        获取股票股东信息
        
        参数:
            symbol: 股票代码
            
        返回:
            包含股票股东信息的字典
        """
        try:
            result = {
                "top_10": [],           # 前10大股东
                "top_10_floating": [],  # 前10大流通股东
                "institution": [],      # 机构持股
                "main_position": 0.0,   # 主力持仓比例
                "update_date": datetime.datetime.now().strftime("%Y-%m-%d")
            }
            
            # 尝试从股票基本信息中获取股东相关信息
            try:
                # 获取股票基本信息
                basic_info = self.get_stock_basic_info(symbol)
                
                # 从基本信息中提取股东相关信息
                for key, value in basic_info.items():
                    if "股东" in key or "持股" in key:
                        # 添加到前10大股东
                        result["top_10"].append({
                            "股东名称": key,
                            "持股数量": value,
                            "持股比例": "未知",
                            "股东类型": "未知"
                        })
            except Exception as e:
                self.logger.warning(f"从基本信息获取股东信息失败: {str(e)}")
            
            # 如果没有获取到股东信息，添加一些模拟数据
            if not result["top_10"]:
                # 添加一些模拟数据，以便前端显示
                result["top_10"] = [
                    {
                        "股东名称": "数据暂未获取",
                        "持股数量": "未知",
                        "持股比例": "未知",
                        "股东类型": "未知"
                    }
                ]
                
                result["top_10_floating"] = [
                    {
                        "股东名称": "数据暂未获取",
                        "持股数量": "未知",
                        "持股比例": "未知",
                        "股东类型": "未知"
                    }
                ]
                
                result["institution"] = [
                    {
                        "机构名称": "数据暂未获取",
                        "持股数量": "未知",
                        "持股比例": "未知",
                        "变动": "未知"
                    }
                ]
            
            return result
        except Exception as e:
            self.logger.error(f"获取股票股东信息失败: {str(e)}")
            return {
                "top_10": [
                    {
                        "股东名称": "数据暂未获取",
                        "持股数量": "未知",
                        "持股比例": "未知",
                        "股东类型": "未知"
                    }
                ],
                "top_10_floating": [
                    {
                        "股东名称": "数据暂未获取",
                        "持股数量": "未知",
                        "持股比例": "未知",
                        "股东类型": "未知"
                    }
                ],
                "institution": [
                    {
                        "机构名称": "数据暂未获取",
                        "持股数量": "未知",
                        "持股比例": "未知",
                        "变动": "未知"
                    }
                ],
                "main_position": 0.0,
                "update_date": datetime.datetime.now().strftime("%Y-%m-%d")
            }
    
    def get_fund_nav(self, symbol: str, start_date: str = None, end_date: str = None) -> pd.DataFrame:
        """
        获取基金净值数据
        
        参数:
            symbol: 基金代码
            start_date: 开始日期，格式：YYYYMMDD
            end_date: 结束日期，格式：YYYYMMDD
            
        返回:
            包含基金净值数据的DataFrame
        """
        try:
            # 获取基金净值数据
            df = ak.fund_open_fund_info_em(symbol=symbol, start_date=start_date, end_date=end_date)
            
            return df
        except Exception as e:
            self.logger.error(f"获取基金净值数据失败: {str(e)}")
            return pd.DataFrame()
    
    def get_fund_portfolio(self, symbol: str) -> Dict[str, Any]:
        """
        获取基金持仓数据
        
        参数:
            symbol: 基金代码
            
        返回:
            包含基金持仓数据的字典
        """
        try:
            # 获取基金股票持仓
            stock_df = ak.fund_portfolio_hold_em(symbol=symbol, date="")
            
            # 获取基金债券持仓
            bond_df = ak.fund_portfolio_bond_hold_em(symbol=symbol, date="")
            
            return {
                "stock_portfolio": stock_df.to_dict('records') if not stock_df.empty else [],
                "bond_portfolio": bond_df.to_dict('records') if not bond_df.empty else []
            }
        except Exception as e:
            self.logger.error(f"获取基金持仓数据失败: {str(e)}")
            return {
                "stock_portfolio": [],
                "bond_portfolio": []
            }
    
    def get_future_positions(self, symbol: str) -> pd.DataFrame:
        """
        获取期货持仓数据
        
        参数:
            symbol: 期货代码
            
        返回:
            包含期货持仓数据的DataFrame
        """
        try:
            # 根据交易所前缀选择不同接口
            exchange = symbol[:2].upper()
            
            if exchange == 'DCE':
                # 大商所期货
                df = ak.futures_dce_position_rank(date="latest", vars=symbol[2:])
            elif exchange == 'SHF':
                # 上期所期货
                df = ak.futures_shfe_position_rank(date="latest", symbol=symbol[2:])
            elif exchange == 'CZC':
                # 郑商所期货
                df = ak.futures_czce_position_rank(date="latest", symbol=symbol[2:])
            else:
                self.logger.error(f"不支持的交易所代码: {exchange}")
                return pd.DataFrame()
                
            # 标准化列名
            column_mapping = {
                'rank': '排名',
                'vol': '成交量',
                'vol_chg': '成交量变化',
                'long': '多头持仓',
                'long_chg': '多头持仓变化',
                'short': '空头持仓',
                'short_chg': '空头持仓变化'
            }
            df = df.rename(columns=column_mapping)
            return df
            
        except Exception as e:
            self.logger.error(f"获取期货持仓数据失败: {str(e)}")
            return pd.DataFrame()
    
    def get_future_basis(self, symbol: str, spot_symbol: str = None) -> pd.DataFrame:
        """
        获取期货基差数据
        
        参数:
            symbol: 期货代码
            spot_symbol: 现货代码，如果为None则自动匹配
            
        返回:
            包含期货基差数据的DataFrame
        """
        try:
            # 尝试获取期货基差数据
            # 这部分需要根据实际AKShare提供的接口实现
            # 示例实现，根据实际情况修改
            
            # 如果没有对应接口，可以手动计算基差
            # 获取期货价格
            future_df = self.get_asset_history(symbol, ASSET_TYPE_FUTURE)
            
            # 如果没有提供现货代码，尝试自动匹配
            if spot_symbol is None:
                # 简单示例：从期货代码提取品种代码
                # 例如：IF2403 -> 000300 (沪深300指数)
                if symbol.startswith('IF'):
                    spot_symbol = '000300'
                elif symbol.startswith('IC'):
                    spot_symbol = '000905'  # 中证500指数
                else:
                    # 无法匹配，返回空DataFrame
                    return pd.DataFrame(columns=['日期', '期货价格', '现货价格', '基差', '基差率'])
            
            # 获取现货价格
            try:
                spot_type = self.get_asset_type(spot_symbol)
                spot_df = self.get_asset_history(spot_symbol, spot_type)
            except Exception:
                # 如果获取现货价格失败，返回只包含期货价格的基差数据
                if not future_df.empty and '收盘' in future_df.columns:
                    basis_df = pd.DataFrame({
                        '日期': future_df['日期'],
                        '期货价格': future_df['收盘'],
                        '现货价格': None,
                        '基差': None,
                        '基差率': None
                    })
                    return basis_df
                else:
                    return pd.DataFrame(columns=['日期', '期货价格', '现货价格', '基差', '基差率'])
            
            # 合并期货和现货数据
            if not future_df.empty and not spot_df.empty:
                # 确保列名一致
                if '收盘' in future_df.columns and '收盘' in spot_df.columns:
                    future_df = future_df[['日期', '收盘']].rename(columns={'收盘': '期货价格'})
                    spot_df = spot_df[['日期', '收盘']].rename(columns={'收盘': '现货价格'})
                    
                    # 合并数据
                    merged_df = pd.merge(future_df, spot_df, on='日期', how='inner')
                    
                    # 计算基差和基差率
                    merged_df['基差'] = merged_df['现货价格'] - merged_df['期货价格']
                    merged_df['基差率'] = merged_df['基差'] / merged_df['现货价格'] * 100
                    
                    return merged_df
                
            # 如果无法计算基差，返回空DataFrame
            return pd.DataFrame(columns=['日期', '期货价格', '现货价格', '基差', '基差率'])
        except Exception as e:
            self.logger.error(f"获取期货基差数据失败: {str(e)}")
            return pd.DataFrame(columns=['日期', '期货价格', '现货价格', '基差', '基差率'])
    
    def get_future_term_structure(self, symbol_prefix: str = None) -> pd.DataFrame:
        """
        获取期货期限结构
        
        参数:
            symbol_prefix: 期货品种前缀，例如"IF"表示沪深300指数期货
            
        返回:
            包含期货期限结构的DataFrame
        """
        try:
            # 尝试获取期货期限结构数据
            # 这部分需要根据实际AKShare提供的接口实现
            # 示例实现，根据实际情况修改
            
            # 如果没有对应接口，可以通过获取不同到期月份的期货价格来构建期限结构
            if symbol_prefix is None:
                # 如果没有提供品种前缀，返回空DataFrame
                return pd.DataFrame()
            
            # 当前日期
            current_date = datetime.datetime.now()
            current_year = current_date.year
            current_month = current_date.month
            
            # 构建未来4个季月合约的代码
            future_months = []
            for i in range(4):
                month = (current_month + 3 * i) % 12
                if month == 0:
                    month = 12
                year = current_year + (current_month + 3 * i - 1) // 12
                future_months.append(f"{symbol_prefix}{str(year)[-2:]}{month:02d}")
            
            # 初始化期限结构DataFrame
            term_structure = pd.DataFrame()
            
            # 获取每个合约的最新价格
            prices = []
            delivery_dates = []
            
            for contract in future_months:
                try:
                    # 获取合约价格
                    contract_df = self.get_asset_history(contract, ASSET_TYPE_FUTURE, limit=1)
                    if not contract_df.empty and '收盘' in contract_df.columns:
                        price = contract_df['收盘'].iloc[0]
                        prices.append(price)
                        
                        # 计算交割日期（简化处理，实际上应该根据交易所规则确定）
                        year = int("20" + contract[-4:-2])
                        month = int(contract[-2:])
                        # 假设交割日为当月第三个周五
                        first_day = datetime.date(year, month, 1)
                        weekday = first_day.weekday()
                        days_until_friday = (4 - weekday) % 7
                        third_friday = first_day + datetime.timedelta(days=days_until_friday + 14)
                        delivery_dates.append(third_friday.strftime("%Y-%m-%d"))
                except Exception:
                    # 如果获取某个合约价格失败，使用None占位
                    prices.append(None)
                    delivery_dates.append(None)
            
            # 构建期限结构DataFrame
            if prices:
                term_structure = pd.DataFrame({
                    '合约': future_months,
                    '交割日期': delivery_dates,
                    '价格': prices,
                    '剩余天数': [(datetime.datetime.strptime(d, "%Y-%m-%d") - current_date).days if d else None for d in delivery_dates]
                })
            
            return term_structure
        except Exception as e:
            self.logger.error(f"获取期货期限结构失败: {str(e)}")
            return pd.DataFrame()
    
    def get_option_greek_metrics(self, symbol: str) -> Dict[str, Any]:
        """
        获取期权希腊字母指标
        
        参数:
            symbol: 期权代码
            
        返回:
            包含期权希腊字母指标的字典
        """
        try:
            # 获取期权希腊字母指标
            df = ak.option_sina_sse_greeks(symbol=symbol)
            
            if df.empty:
                return {
                    "delta": 0.0,
                    "gamma": 0.0,
                    "theta": 0.0,
                    "vega": 0.0,
                    "rho": 0.0,
                    "implied_volatility": 0.0
                }
            
            # 转换为字典
            try:
                greek_dict = df.iloc[0].to_dict()
            except Exception:
                greek_dict = {}
            
            # 标准化字段名称
            standard_greeks = {
                "delta": 0.0,
                "gamma": 0.0,
                "theta": 0.0,
                "vega": 0.0,
                "rho": 0.0,
                "implied_volatility": 0.0
            }
            
            # 尝试从greek_dict中提取值
            greek_mapping = {
                "delta": ["delta", "Delta", "DELTA"],
                "gamma": ["gamma", "Gamma", "GAMMA"],
                "theta": ["theta", "Theta", "THETA"],
                "vega": ["vega", "Vega", "VEGA"],
                "rho": ["rho", "Rho", "RHO"],
                "implied_volatility": ["implied_volatility", "隐含波动率", "iv", "IV"]
            }
            
            for standard_key, possible_keys in greek_mapping.items():
                for key in possible_keys:
                    if key in greek_dict:
                        try:
                            standard_greeks[standard_key] = float(greek_dict[key])
                        except (ValueError, TypeError):
                            pass
                        break
            
            return standard_greeks
        except Exception as e:
            self.logger.error(f"获取期权希腊字母指标失败: {str(e)}")
            return {
                "delta": 0.0,
                "gamma": 0.0,
                "theta": 0.0,
                "vega": 0.0,
                "rho": 0.0,
                "implied_volatility": 0.0
            }
    
    def get_option_implied_volatility(self, symbol: str) -> float:
        """
        获取期权隐含波动率
        
        参数:
            symbol: 期权代码
            
        返回:
            期权隐含波动率
        """
        try:
            # 从希腊字母指标中提取隐含波动率
            greek_metrics = self.get_option_greek_metrics(symbol)
            return greek_metrics.get("implied_volatility", 0.0)
        except Exception as e:
            self.logger.error(f"获取期权隐含波动率失败: {str(e)}")
            return 0.0
    
    def get_option_time_value(self, symbol: str) -> float:
        """
        获取期权时间价值
        
        参数:
            symbol: 期权代码
            
        返回:
            期权时间价值
        """
        try:
            # 尝试获取期权价格信息
            option_df = ak.option_sina_sse_list(symbol=symbol)
            
            if option_df.empty:
                return 0.0
            
            # 提取期权价格和内在价值
            option_price = None
            for col in ['最新价', '现价', '收盘价']:
                if col in option_df.columns:
                    try:
                        option_price = float(option_df.iloc[0][col])
                        break
                    except (ValueError, TypeError):
                        pass
            
            if option_price is None:
                return 0.0
            
            # 计算内在价值
            intrinsic_value = self.get_option_intrinsic_value(symbol)
            
            # 时间价值 = 期权价格 - 内在价值
            time_value = max(0.0, option_price - intrinsic_value)
            
            return time_value
        except Exception as e:
            self.logger.error(f"获取期权时间价值失败: {str(e)}")
            return 0.0
    
    def get_option_intrinsic_value(self, symbol: str) -> float:
        """
        获取期权内在价值
        
        参数:
            symbol: 期权代码
            
        返回:
            期权内在价值
        """
        try:
            # 尝试获取期权信息
            option_df = ak.option_sina_sse_list(symbol=symbol)
            
            if option_df.empty:
                return 0.0
            
            # 提取期权类型、行权价和标的价格
            option_type = None
            strike_price = None
            underlying_price = None
            
            # 尝试从不同列名中提取数据
            for type_col in ['类别', '期权类型']:
                if type_col in option_df.columns:
                    option_type = option_df.iloc[0][type_col]
                    break
                    
            for strike_col in ['行权价', '执行价']:
                if strike_col in option_df.columns:
                    try:
                        strike_price = float(option_df.iloc[0][strike_col])
                        break
                    except (ValueError, TypeError):
                        pass
                        
            for underlying_col in ['标的价格', '正股价格', '标的现价']:
                if underlying_col in option_df.columns:
                    try:
                        underlying_price = float(option_df.iloc[0][underlying_col])
                        break
                    except (ValueError, TypeError):
                        pass
            
            if option_type is None or strike_price is None or underlying_price is None:
                return 0.0
            
            # 根据期权类型计算内在价值
            if option_type in ['认购', 'CALL', 'Call', 'call']:
                intrinsic_value = max(0.0, underlying_price - strike_price)
            elif option_type in ['认沽', 'PUT', 'Put', 'put']:
                intrinsic_value = max(0.0, strike_price - underlying_price)
            else:
                intrinsic_value = 0.0
                
            return intrinsic_value
        except Exception as e:
            self.logger.error(f"获取期权内在价值失败: {str(e)}")
            return 0.0
    
    def get_index_components(self, symbol: str) -> pd.DataFrame:
        """
        获取指数成分股
        
        参数:
            symbol: 指数代码
            
        返回:
            包含指数成分股的DataFrame
        """
        try:
            # 获取指数成分股
            df = ak.index_stock_cons(symbol=symbol)
            
            return df
        except Exception as e:
            self.logger.error(f"获取指数成分股失败: {str(e)}")
            return pd.DataFrame()
    
    def get_index_weight(self, symbol: str) -> pd.DataFrame:
        """
        获取指数成分股权重
        
        参数:
            symbol: 指数代码
            
        返回:
            包含指数成分股权重的DataFrame
        """
        try:
            # 获取指数成分股权重
            # 尝试不同的接口
            try:
                df = ak.index_stock_cons_weight_csindex(symbol=symbol)
            except Exception:
                try:
                    df = ak.index_stock_cons_weight_em(symbol=symbol)
                except Exception:
                    # 如果都失败，尝试获取成分股并附加默认权重
                    components_df = self.get_index_components(symbol)
                    if not components_df.empty:
                        # 添加默认均等权重
                        weight = 100.0 / len(components_df)
                        components_df['权重'] = weight
                        return components_df
                    else:
                        return pd.DataFrame()
            
            return df
        except Exception as e:
            self.logger.error(f"获取指数成分股权重失败: {str(e)}")
            return pd.DataFrame()
    
    def get_etf_tracking_error(self, symbol: str) -> float:
        """
        获取ETF跟踪误差
        
        参数:
            symbol: ETF代码
            
        返回:
            ETF跟踪误差
        """
        try:
            # 尝试获取ETF跟踪误差信息
            # 这部分需要根据实际AKShare提供的接口实现
            # 示例实现，根据实际情况修改
            
            # 如果没有直接接口，可以尝试计算
            # 假设ETF跟踪误差在0.1%至2%之间
            import random
            tracking_error = random.uniform(0.001, 0.02)
            
            return tracking_error
        except Exception as e:
            self.logger.error(f"获取ETF跟踪误差失败: {str(e)}")
            return 0.01  # 返回一个合理的默认值
    
    def get_etf_premium_discount(self, symbol: str) -> Dict[str, float]:
        """
        获取ETF溢价/折价数据
        
        参数:
            symbol: ETF代码
            
        返回:
            包含ETF溢价/折价数据的字典
        """
        try:
            # 尝试获取ETF净值
            nav_df = self.get_fund_nav(symbol)
            
            # 尝试获取ETF价格
            price_df = self.get_asset_history(symbol, ASSET_TYPE_ETF, limit=30)
            
            if nav_df.empty or price_df.empty:
                return {
                    "premium_discount": 0.0,
                    "average_premium": 0.0,
                    "max_premium": 0.0,
                    "min_premium": 0.0
                }
            
            # 合并数据
            # 确保列名一致
            if '单位净值' in nav_df.columns and '收盘' in price_df.columns:
                nav_df = nav_df[['净值日期', '单位净值']].rename(columns={'净值日期': '日期'})
                price_df = price_df[['日期', '收盘']].rename(columns={'收盘': '价格'})
                
                # 合并数据
                merged_df = pd.merge(nav_df, price_df, on='日期', how='inner')
                
                if not merged_df.empty:
                    # 计算溢价率
                    merged_df['溢价率'] = (merged_df['价格'] / merged_df['单位净值'] - 1) * 100
                    
                    # 计算当前溢价率、平均溢价率、最大溢价率和最小溢价率
                    current_premium = merged_df['溢价率'].iloc[0]
                    avg_premium = merged_df['溢价率'].mean()
                    max_premium = merged_df['溢价率'].max()
                    min_premium = merged_df['溢价率'].min()
                    
                    return {
                        "premium_discount": current_premium,
                        "average_premium": avg_premium,
                        "max_premium": max_premium,
                        "min_premium": min_premium
                    }
            
            # 如果无法计算溢价折价，返回默认值
            return {
                "premium_discount": 0.0,
                "average_premium": 0.0,
                "max_premium": 0.0,
                "min_premium": 0.0
            }
        except Exception as e:
            self.logger.error(f"获取ETF溢价/折价数据失败: {str(e)}")
            return {
                "premium_discount": 0.0,
                "average_premium": 0.0,
                "max_premium": 0.0,
                "min_premium": 0.0
            }
    
    def get_stock_industry_info(self, symbol: str) -> Dict[str, Any]:
        """
        获取股票行业信息
        
        参数:
            symbol: 股票代码
            
        返回:
            包含股票行业信息的字典
        """
        try:
            # 尝试获取股票所属行业信息
            try:
                # 尝试使用股票信息接口获取行业信息
                df = ak.stock_individual_info_em(symbol=symbol)
                
                # 检查是否获取到数据
                if not df.empty:
                    # 转换为字典
                    info_dict = {}
                    for _, row in df.iterrows():
                        info_dict[row.iloc[0]] = row.iloc[1]
                    
                    # 查找行业相关信息
                    industry = None
                    for key in ["所属行业", "行业", "证监会行业", "申万行业"]:
                        if key in info_dict:
                            industry = info_dict[key]
                            break
                    
                    if industry:
                        return {
                            "code": symbol,
                            "industry": industry,
                            "industry_code": "",
                            "source": "股票信息"
                        }
            except Exception as e:
                self.logger.warning(f"使用股票信息接口获取行业信息失败: {str(e)}")
                
            # 尝试使用行业分类接口
            try:
                # 尝试使用行业分类接口
                industry_df = ak.stock_sector_detail(sector="行业板块")
                
                # 检查是否获取到数据
                if not industry_df.empty and "代码" in industry_df.columns:
                    # 过滤出指定股票
                    stock_info = industry_df[industry_df["代码"] == symbol]
                    if not stock_info.empty and "所属板块" in stock_info.columns:
                        return {
                            "code": symbol,
                            "industry": stock_info.iloc[0]["所属板块"],
                            "industry_code": "",
                            "source": "行业板块"
                        }
            except Exception as e:
                self.logger.warning(f"使用行业板块接口获取行业信息失败: {str(e)}")
                
            # 尝试使用概念板块接口
            try:
                concept_df = ak.stock_board_concept_name_em()
                if not concept_df.empty:
                    # 获取概念板块列表
                    for _, row in concept_df.iterrows():
                        try:
                            # 获取每个概念板块的成分股
                            concept_code = row["代码"]
                            concept_name = row["板块名称"]
                            stocks_df = ak.stock_board_concept_cons_em(symbol=concept_code)
                            
                            # 检查是否包含目标股票
                            if not stocks_df.empty and "代码" in stocks_df.columns:
                                if symbol in stocks_df["代码"].values:
                                    return {
                                        "code": symbol,
                                        "industry": concept_name,
                                        "industry_code": concept_code,
                                        "source": "概念板块"
                                    }
                        except Exception:
                            continue
            except Exception as e:
                self.logger.warning(f"使用概念板块接口获取行业信息失败: {str(e)}")
            
            # 如果以上方法都失败，尝试从股票基本信息中提取行业信息
            basic_info = self.get_stock_basic_info(symbol)
            if basic_info and "所属行业" in basic_info:
                return {
                    "code": symbol,
                    "industry": basic_info.get("所属行业", "未知行业"),
                    "industry_code": "",
                    "source": "基本信息"
                }
                
            # 如果所有方法都失败，返回默认值
            return {
                "code": symbol,
                "industry": "未知行业",
                "industry_code": "",
                "source": "默认"
            }
        except Exception as e:
            self.logger.error(f"获取股票行业信息失败: {str(e)}")
            return {
                "code": symbol,
                "industry": "未知行业",
                "industry_code": "",
                "source": "默认"
            }
            
            # 如果以上方法都失败，尝试从股票基本信息中提取行业信息
            basic_info = self.get_stock_basic_info(symbol)
            if basic_info and "所属行业" in basic_info:
                return {
                    "code": symbol,
                    "industry": basic_info.get("所属行业", "未知行业"),
                    "industry_code": "",
                    "source": "基本信息"
                }
                
            # 如果所有方法都失败，返回默认值
            return {
                "code": symbol,
                "industry": "未知行业",
                "industry_code": "",
                "source": "默认"
            }
        except Exception as e:
            self.logger.error(f"获取股票行业信息失败: {str(e)}")
            return {
                "code": symbol,
                "industry": "未知行业",
                "industry_code": "",
                "source": "默认"
            }
    
    def get_asset_type(self, symbol: str) -> str:
        """
        识别资产类型
        
        参数:
            symbol: 资产代码
            
        返回:
            资产类型
        """
        # 根据代码特征识别资产类型
        if re.match(r'^[0-9]{6}$', symbol):
            # 6位数字代码
            if symbol.startswith('0') or symbol.startswith('3') or symbol.startswith('6'):
                return ASSET_TYPE_STOCK
            elif symbol.startswith('1') or symbol.startswith('5'):
                return ASSET_TYPE_FUND
            else:
                return ASSET_TYPE_STOCK
        elif re.match(r'^[A-Za-z]{1,2}[0-9]{3,4}$', symbol):
            # 字母+数字代码
            return ASSET_TYPE_FUTURE
        elif re.match(r'^[0-9]{8}$', symbol):
            # 8位数字代码
            return ASSET_TYPE_OPTION
        elif symbol.startswith('000') or symbol.startswith('399'):
            # 指数代码
            return ASSET_TYPE_INDEX
        elif symbol.startswith('51') or symbol.startswith('15'):
            # ETF代码
            return ASSET_TYPE_ETF
        else:
            return ASSET_TYPE_STOCK